#ifndef bck_h
#define bck_h

// this header needs
#include "ank1.h"

// BCK files of Super Mario Galaxy

// structure
// magic - 32 bits ("J3D1" or "1D3J")
// file type - 32 bits ("bck1" or "1kcb")
// file size - 32 bits
// section count - 32 bits
// unknown 1 - 16 bytes (always 0xFF all bytes?)
// ank1 section - its size bruh

// header information (can be determined from the ank1 information)
typedef struct {          // size on binary file
  owl_umax magic;         // 32bits
  owl_umax file_type;     // 32bits
  owl_umax file_size;     // 32bits
  owl_umax section_count; // 32bits
  owl_byte * unknown1;    // 16 bytes
} owl_smg_bck_header;
// ^ all of those except the file_size are constants (afaik)
// if there is some "special" property then idk

// the actual structure
typedef struct {
  owl_smg_bck_header * header;
  owl_smg_ank1 * ank1;
} owl_smg_bck;

// all the constants at once
owl_umax OWL_SMG_BCK_MAGIC[][2] = {{0x4A334431, 0x3144334A}}; // "J3D1", "1D3J" (int form, easier for checks)
owl_umax OWL_SMG_BCK_FILE_TYPE[][2] = {{0x62636B31, 0x316B6362}}; // "bck1", "1kcb"
#define OWL_SMG_BCK_SECTION_COUNT 1
#define OWL_SMG_BCK_UNKNOWN1_LENGTH 16
owl_byte OWL_SMG_BCK_UNKNOWN1[OWL_SMG_BCK_UNKNOWN1_LENGTH] =
{
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF
};

// enum with the possible codes a BCK file will present while analizing it
// all errors are named to indicate the place of the read error (in the best case)
// other errors are related to logic errors when reading the raw string
typedef enum
{
  OWL_SMG_BCK_ERR_ALL_GOOD,
  
  OWL_SMG_BCK_ERR_FUNC_PARAMS,
  OWL_SMG_BCK_ERR_STR_SIZE,
  OWL_SMG_BCK_ERR_MEM_ALLOC,
  
  OWL_SMG_BCK_ERR_MAGIC,
  OWL_SMG_BCK_ERR_FILE_TYPE,
  OWL_SMG_BCK_ERR_FILE_SIZE,
  OWL_SMG_BCK_ERR_SECTION_COUNT,
  OWL_SMG_BCK_ERR_UNKNOWN1,
  OWL_SMG_BCK_ERR_ANK1_SECTION,
  
  OWL_SMG_BCK_ERR_LIMIT,
} owl_smg_bck_err_cd;

// global variable for the owl_create_smg_bck()
// function used by the owl_get_err_cd_smg_bck()
owl_smg_bck_err_cd OWL_SMG_BCK_ERR_CD = OWL_SMG_BCK_ERR_ALL_GOOD;
owl_umax OWL_SMG_BCK_ERR_READ_POS = 0;

// basic functions
owl_bool owl_check_smg_bck_header_pointer(owl_byte * src, owl_umax size);
owl_bool owl_check_smg_bck_pointer(owl_byte * src, owl_umax size);
owl_bool owl_check_smg_bck_all(owl_smg_bck * bck, owl_umax size);
owl_smg_bck * owl_create_smg_bck(owl_str * raw, owl_endian endian);
owl_umax owl_free_smg_bck(owl_smg_bck * bck);
owl_umax owl_print_smg_bck(owl_byte * src, owl_umax size);
owl_char owl_comp_smg_bck(owl_byte * bck1, owl_byte * bck2);

// specific functions
owl_bool owl_get_smg_bck_header(owl_smg_bck * bck);
owl_umax owl_get_smg_bck_bin_size(owl_smg_bck * bck);
owl_smg_bck_err_cd owl_get_err_cd_smg_bck(owl_str * raw, owl_endian endian);
owl_smg_bck * owl_get_smg_bck_min_args(owl_smg_ank1 * ank1);
owl_str * owl_get_smg_bck_as_str(owl_smg_bck * bck, owl_endian endian);

#include "bck.c"

#endif // bck_h
